package edu.hit.pact.pgse.communication;

import java.io.IOException;
import java.net.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class CommUtil {
	private Log logger;
	private IoConnector connector;
	private ConnectFuture connectFuture;
	
	public CommUtil(){
		logger = LogFactory.getLog(CommUtil.class);
	}
	
	public CommUtil(IoHandler handler){
		logger = LogFactory.getLog(CommUtil.class);
		connector = new NioSocketConnector();
		connector.setConnectTimeoutMillis(60*1000);/// The default value is 1 minute

		/**
		 * ObjectSerializationCodecFactory!!
		 */
		connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
		connector.setHandler(handler);
	}
	
	//return null stand for can not connect to address specified.
	//else return the IoSession builded.
	public IoSession setConnector(SocketAddress addr) {
		// Start connect
		connectFuture = connector.connect(addr);
		connectFuture.join();
		return connectFuture.getSession();
	}
	
	public void closeConnector(){
		//Wait for the connection attempt to be finished.
		connectFuture.awaitUninterruptibly();
		connectFuture.getSession().getCloseFuture().awaitUninterruptibly();
		connector.dispose();
	}
	
	public void setAcceptor(IoHandler handler, int serverPort){
		// create acceptor
		SocketAcceptor acceptor = new NioSocketAcceptor();
		acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
		acceptor.setHandler(handler);

        // Bind
        try {
			acceptor.bind(new InetSocketAddress(serverPort));
		} catch (IOException e) {
			logger.error("When bind to " + serverPort + " port, server meets unexpected exception.", e);
		}
		
		logger.info("MessageReceiver Listening on port " + serverPort);
	}
}
